﻿#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QSerialPort>
#include <QDebug>
#include <QMessageBox>
#include <QSerialPortInfo>
#include <QStandardItem>
#include <QTimer>
#include <QTime>
#include <QFileDialog>
#include <QFileInfo>
#include <QFile>
#include <QInputDialog>
#include <QLabel>
#include <QFontDialog>
#include <QColorDialog>
#include <QHostInfo>
#include <QNetworkInterface>
#include <QTcpServer>
#include <QTcpSocket>
#include <QUdpSocket>
#include <QRegExp>
#include "mytcpprogress.h"
#include <QList>
#include <QMap>
#include <QThread>
#include <QTextBrowser>
#include <QCloseEvent>
#include <QMetaType>
#include "mytcpserver.h"

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

private slots:


    void on_btnConnect_clicked();//连接按钮的槽函数

    void on_combSerialPort_currentTextChanged(const QString &arg1);

    void on_combBaudRate_currentTextChanged(const QString &arg1);

    void on_combDataBits_currentIndexChanged(int index);

    void on_combParity_currentIndexChanged(int index);

    void on_combStopBit_currentIndexChanged(int index);

    void on_actUpdate_triggered();

    void on_btnSend_clicked();

    void on_serialPort_readyRead();//用于响应接受信息的槽函数

    void on_actClear_triggered();

    void on_btnClearSendText_clicked();

    void on_timer_out();//响应定时器的函数

    void on_spinBoxSendTime_valueChanged(int arg1);

    void on_cheReSend_stateChanged(int arg1);

    void setSetingVisiable(bool visiable);//控制UI设置是否可见

    void on_reRsend_checked();//发送模式为重复发送时的定时器响应函数

    void on_textMainSend_textChanged();

    void on_btnClearAcceptText_clicked();

    void on_textMainAccept_textChanged();

    void on_combFlowControl_currentIndexChanged(int index);

    void on_btnBrowerFile_clicked();

    void on_editFilePath_textChanged(const QString &arg1);

    void on_btnSendFile_clicked();

    void on_actSerialPortWindow_triggered();

    void on_actNetworkWindow_triggered();

    void on_Window_changed(QAction* action);//响应界面切换的函数
    void on_btnSerialSave_clicked();

    void on_btnSerialLogSave_clicked();

    void on_actCustomBundRate_triggered();

    void on_radioSendHEX_clicked(bool checked);

    void on_radioSendAscll_clicked(bool checked);

    void on_actSetFont_triggered();

    void on_actSetBackColor_triggered();

    void on_actDefaultSetting_triggered();

    void on_btnPauseAccept_clicked();

    void on_pushButton_clicked();

    //以下代码为网络调试使用
    //以下代码为网络调试使用
    //以下代码为网络调试使用
    void iniNetWindow();//初始化网络调试窗口

    QList<QHostAddress> getIPv4Address();//返回本机地址

    void on_combProtocolNet_currentIndexChanged(int index);

    void on_btnListenNet_clicked();

    void on_actUpdateNet_triggered();

    void on_socket_stateChanged(QAbstractSocket::SocketState state);//用于响应socket对象连接状态改变的槽函数

    void on_socket_connected(qintptr);//当socket连接成功时的响应函数

    void on_socket_disconnected();//当socket断开连接时的响应函数

    void on_btnSendNet_clicked();

    void on_timerNet_timeout();//响应保活计时器的槽函数

    void on_btnClearSendNet_clicked();

    void on_btnClearRecNet_clicked();

    void on_textRecNet_textChanged();

    void on_textSendNet_textChanged();

    void on_tcpSocket_readyRead();//tcpsocket读写槽函数

    void on_btnSaveLogNet_clicked();

    void on_cheReSendNet_stateChanged(int arg1);

    void on_spinBoxSendIntervalNet_valueChanged(int arg1);

    void on_timerReSend_timeout();//用于响应网络调试重复发送定时器的槽函数

    void on_btnRecNet_clicked();

    void on_radioSendAscllNet_clicked(bool checked);

    void on_radioSendHexNet_clicked(bool checked);

    void on_btnSaveDateNet_clicked();

    void on_combUdpCastModeNet_currentIndexChanged(int index);

    void on_udpSocket_readyRead();//响应udp通信接收数据的槽函数

    void on_btnJoinBroadMulticastNet_clicked();

    void on_asTcpClient_Connecte();//当作为tcp客户端连接成功时的响应槽函数

    //以下信号用于tcp多线程
    void on_progress_connected(QString address,int index);//当线程套接字连接成功时
    void on_progress_disconnected(QString peerAddress,int index);//当线程套接字连接断开时
    void on_progress_newMessage(QByteArray recData,int index);//当子线程接收到消息时
    void on_tabWidgetNet_currentChanged(int index);
    void onWidgetTextChanged();//当当前界面的文本内容发生变化时判断保存,清理按钮是否可用


    void on_btnNewTcpServiceNet_clicked();

signals:
    //以下代码用于tcp多线程
    void createTcpConnect(qintptr,int index);//用于主线程接收到新tcp链接时将对方套接字发送给子线程的信号
    void sendMessage(QByteArray sendData,int index);//用于主线程发送消息
    void newTcpServiceProgress(QString address,int port,int index);//用于主线程控制子线程创建tcp客户端的信号


protected:
    void closeEvent(QCloseEvent* e);//重写close函数,保证程序退出前释放所有资源


private:
    Ui::MainWindow *ui;

    QSerialPort m_serialPort;//主要串口实例
    QFile m_sendFile;//发送的文件实例
    int m_sendFileSignalSize;//记录发送文件的单次长度
    QString m_originalAcceptString;//用于记录串口接收到的数据,没有任何加工

    QList<QSerialPortInfo> serialPortList;//可用端口列表

    bool m_isConnect;//记录串口状态
    bool m_isAcceptRec;//用于记录是否允许接收

    QTimer m_reSendTimer;//重复发送信息的定时器
    int m_reSendInterval;//重复发送信息的间隔时间

    QByteArray m_recByteArray;//用于记录接收原生的二进制数组


    void iniSerialPort();//按照界面显示信息初始化串口设置

    bool setConnectStatue(bool statue);//点击连接按钮触发的函数,返回值表示操作是否成功,参数表示打开还是关闭

    int updateSerialPortList();//更新可用端口列表,同步更新到UI界面的端口号comb,并返回可用端口数量

    int m_recCountSerial;//用于串口接收数据的计数
    int m_sendCountSerial;//用于串口发送数据的计数

    QLabel m_statueLab0;//状态栏:通信方式
    QLabel m_statueLab1;//状态栏:连接状态
    QLabel m_statueLab2;//状态栏:串口号
    QLabel m_statueLab3;//状态栏:发送格式
    QLabel m_statueLab4txt;//发送数据长度前的文字
    QLabel m_statueLab4;//状态栏:发送数据的长度
    QLabel m_statueLab5txt;//接收数据长度前的文字
    QLabel m_statueLab5;//状态栏:接收的数据的长度

    //以下代码为网络调试使用
    //以下代码为网络调试使用
    //以下代码为网络调试使用
    mytcpserver* m_tcpServer;//tcp服务器指针
    QTcpSocket* m_tcpSocket;//tcp套接字指针
    QUdpSocket* m_udpSocket;//udp套接字指针

    bool m_isConnectNet;//用于记录网络是否连接

    bool m_isAcceptRecNet;//用于记录是否允许接收

    bool m_isJoinMultiNet;//用于记录是否加入udp组播

    int m_waitForConnectTime;//用于设置作为客户端等待连接的超时时间

    QTimer *m_timerNet;//保活计时器,用于定时检查连接状态

    QTimer *m_timerReSendNet;//用于网络调试重复发送的计时器

    int m_timerReSendNetInterval;//用于记录网络调试重复发送的定时器的触发时间间隔

    QString m_originalAcceptStringNet;//用于网络记录接收到的数据,没有任何加工

    int m_recCountNet;//用于网络接收的字节计数
    int m_sendCountNet;//用于网络发送的字节计数

    bool m_isBindNet;//用于记录udp通信是否绑定

    QList<mytcpprogress*> m_tcpProgerssList;//用于记录作为tcp服务器时的收发程序
    QList<QThread*> m_tcpThreadList;//用于记录作为tcp服务器时的线程
    QList<QTextBrowser*> m_tcpWidgetList;//用于记录作为tcp服务器时的接收文本框
    QList<QByteArray> m_tcpOriRec;//用于记录作为tcp服务器每个窗口接收的原生数据

    int getThreadIndexNet();//获得当前窗口对应的队列索引,如果没有找到返回-1,如果没找到则程序出错
};
#endif // MAINWINDOW_H
